#pragma once
#include <list>
#include "graphics/GrVector.h"
#include "graphics/GrTransform.h"



class CParticles 
{
public:
	CParticles(void);
	virtual ~CParticles(void);
	
    void Clear();
    void LoadParticle(const CGrVector &location, const CGrVector &velocity, const float *color, double energy=1);
    void Render(int width, int height);
    void Display(int width, int height);

    virtual void Update(double dt);
    virtual void Render();

    void SetGravity(bool s) {m_gravity = s;}
    void SetBounce(int b) {m_bounce = b;}
    void SetEmission(bool e) {m_emission = e;}
    void SetDecay(bool d) {m_decay = d;}
    void SetEnergyColor(bool e) {m_energycolor = e;}

    int GetBounce() const {return m_bounce;}
    bool GetEmission() const {return m_emission;}
    bool GetGravity() const {return m_gravity;}
    bool GetDecay() const {return m_decay;}
    bool GetEnergyColor() const {return m_energycolor;}


private:
    struct Particle
    {
        Particle() : p(0, 0, 0), v(0, 0, 0, 0), energy(1) {}

        CGrVector    p;          // Where is it?
        CGrVector    v;          // Velocity
        float       color[3];   // The particle color
        double      energy;

        CGrVector    projected;  // Particle after projection matrix

        bool operator<(const Particle &p) {return projected[2] > p.projected[2];}
    };

    std::list<Particle> m_particles;        // All of our particles

    bool        m_gravity;
    int         m_bounce;

    float     **m_partimage;
    int         m_partimagewidth;
    int         m_partimageheight;
    CGrTransform m_partxform;
    int         m_vp[4];
    bool        m_emission;
    bool        m_decay;
    bool        m_energycolor;

	bool        m_run;
    bool        m_firstdraw;
    DWORD       m_lasttime;

    void ParticleRender(const Particle &p);
    void ParticlesRender();
    void ParticlesUpdate();
    bool TryUpdate(Particle &p, double dt);
};
